package com.zhentao.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdcardUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhentao.domain.SysPlan;
import com.zhentao.domain.SysPreferential;
import com.zhentao.domain.SysUser;
import com.zhentao.domain.infoVo.UserInfoSCVo;
import com.zhentao.domain.infoVo.UserInfoYHJVo;
import com.zhentao.domain.vo.Result;
import com.zhentao.domain.vo.ResultCodeEnum;
import com.zhentao.mapper.SysPreferentialMapper;
import com.zhentao.mapper.SysUserMapper;
import com.zhentao.service.SysPlanService;
import com.zhentao.utils.CodeUtils;
import com.zhentao.service.SysUserService;
import com.zhentao.utils.JwtService;
import com.zhentao.utils.UserUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.TimeUnit;
import com.zhentao.domain.vo.Result;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.HandlerInterceptor;

/**
* @author 86133
* @description 针对表【sys_user】的数据库操作Service实现
* @createDate 2024-08-20 17:17:50
*/
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser>
    implements SysUserService{
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysPreferentialMapper sysPreferentialMapper;
    @Autowired
    private SysPlanService service;
    //查询用户信息
    @Override
    public SysUser getUserInfo() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String header = request.getHeader("Authorization");
        if(StringUtils.checkValNull(header)){
            return null;
        }
        String data = stringRedisTemplate.opsForValue().get("login:data:" + header);
        Map<String, Object> map = JwtService.getClaimsMap(data);
        Integer  id = Integer.valueOf(map.get("userId").toString());
            SysUser byId = this.getById(id);
        List<SysPlan> list = service.list(Wrappers.<SysPlan>lambdaQuery().eq(SysPlan::getUid, id));
        if (list.size()<=0){
            byId.setPlanStatus(0);
            return byId;
        }
        byId.setPlanStatus(1);
        return byId;
    }
    //    修改用户信息
    @Autowired
    private UserUtils utils;
    @Override
    public int updateUserInfo(SysUser sysUser) {
        sysUser.setUid(utils.GetUserId());
        boolean updateById = this.updateById(sysUser);
        return updateById ? 1 : 0;
    }
    //查询收藏站点
    @Override
    public UserInfoSCVo getUserInfoSc(String token) {

        return null;
    }
    //查询优惠卷信息
    @Override
    public List<UserInfoYHJVo> getUserInfoYhj(String token) {
            String dataSc = stringRedisTemplate.opsForValue().get("login:data:" + token);
            Map<String, Object> map = JwtService.getClaimsMap(dataSc);
            Integer  uid = Integer.valueOf(map.get("userId").toString());
             List<UserInfoYHJVo> userInfoYhj = sysUserMapper.getUserInfoYhj(uid);

        userInfoYhj.forEach(userInfoYHJVo -> {
            Long start = userInfoYHJVo.getStartrTime().getTime()/1000;
            Long endTime = userInfoYHJVo.getEndTime().getTime()/1000;
            userInfoYHJVo.setStartDateTime(start);
            userInfoYHJVo.setEndDateTime(endTime);

            // 这是优惠卷的到期日期
            // 将 Date 转换为 Instant，然后转换为 LocalDate
            LocalDate endDateTime = userInfoYHJVo.getEndTime().toInstant()
                    .atZone(ZoneId.systemDefault()) // 使用系统默认时区
                    .toLocalDate();
            // 获取当前日期
            LocalDate currentDate = LocalDate.now();
            // 计算日期差异
            long daysUntilExpiration = ChronoUnit.DAYS.between(currentDate, endDateTime);
            // 判断优惠卷是否过期
            if (daysUntilExpiration < 0) {
                sysPreferentialMapper.updatePreferential(userInfoYHJVo.getPreferentialId());
                userInfoYHJVo.setPreStatus(0);
                System.out.println("优惠卷已过期。");
            } else {
                System.out.println("优惠卷未过期，还有 " + daysUntilExpiration + " 天过期。");
            }

        });
        return userInfoYhj;
    }
    //查询优惠卷信息 不可用
    @Override
    public List<UserInfoYHJVo> getNotUserInfoYhj(String token) {
        String dataSc = stringRedisTemplate.opsForValue().get("login:data:" + token);
        Map<String, Object> map = JwtService.getClaimsMap(dataSc);
        Integer  uid = Integer.valueOf(map.get("userId").toString());
        List<UserInfoYHJVo> notUserInfoYhj = sysUserMapper.getNotUserInfoYhj(uid);
        notUserInfoYhj.forEach(userInfoYHJVo -> {
            Long start = userInfoYHJVo.getStartrTime().getTime()/1000;
            Long endTime = userInfoYHJVo.getEndTime().getTime()/1000;
            userInfoYHJVo.setStartDateTime(start);
            userInfoYHJVo.setEndDateTime(endTime);

        });
        return notUserInfoYhj;
    }

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    @Override
    public Result login(String phone, String code) {
        if(StringUtils.checkValNull(phone)||StringUtils.checkValNull(code)) return Result.build(null, ResultCodeEnum.LOGIN_ERROR);
        boolean flag = CodeUtils.validateMobileNumber(phone);
        if(!flag)return Result.build(null,402,"手机号格式错误");
        SysUser user = this.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getPhone, phone));
        String data = stringRedisTemplate.opsForValue().get("login:phone:" + phone);
        SysUser sysUser = new SysUser();
        if(data.equals(code)) {
            if(BeanUtil.isEmpty(user)){
                sysUser.setPhone(phone);
                this.save(sysUser);
                Map<String,Object> map=new HashMap<>();
                map.put("userId",sysUser.getUid());
                String token = JwtService.createToken(map);
                UUID uuid = UUID.randomUUID();
                stringRedisTemplate.opsForValue().set("login:data:"+uuid,token);
                stringRedisTemplate.opsForHash().put("login:data","login:user:"+uuid,token);
                return Result.build(uuid, 200, "登录成功");
            }else{
                Map<String,Object> map=new HashMap<>();
                map.put("userId",user.getUid());
                String token = JwtService.createToken(map);
                UUID uuid = UUID.randomUUID();
                stringRedisTemplate.opsForValue().set("login:data:"+uuid,token);
                stringRedisTemplate.opsForHash().put("login:data","login:user:"+uuid,token);
                return Result.build(uuid, 200, "登录成功");
            }
        }
        return Result.build(null,400,"登录失败");
    }

    @Override
    public Result getCode(String phone) {
        boolean flag = CodeUtils.validateMobileNumber(phone);
        if(!flag)return Result.build(null,402,"手机号格式错误");
        Long code= (long) (new Random().nextInt(900000)+100000);
        stringRedisTemplate.opsForValue().set("login:phone:"+phone,code.toString(),120, TimeUnit.SECONDS);
        return Result.build(code,200,"生成验证码成功");
    }
//实名验证
    @Override
    public Result realName(SysUser sysUser) {
//        引入登录token
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String header = request.getHeader("Authorization");
        String data = stringRedisTemplate.opsForValue().get("login:data:" + header);
        if (StringUtils.isEmpty(data)){
            return Result.build(null,ResultCodeEnum.LOGIN_ERROR);
        }
        Map<String, Object> map = JwtService.getClaimsMap(data);
        Integer  id = Integer.valueOf(map.get("userId").toString());
//        验证用户输入的信息
        if(StringUtils.checkValNull(sysUser.getCardId())||StringUtils.checkValNull(sysUser.getCardName()))return Result.build(null,ResultCodeEnum.LOGIN_ERROR);
//        根据身份证倒数第二位判性别 1男 2女
        boolean validCard = IdcardUtil.isValidCard(sysUser.getCardId());
        if(!validCard)return Result.build(null,402,"身份证格式错误");
        String substring = sysUser.getCardId().substring(16, 17);
        System.err.println(substring);
        if(Integer.parseInt(substring)%2!=0){
            sysUser.setSex(1);
        }else {
            sysUser.setSex(2);
        }
        boolean valid = IdcardUtil.isValidCard(sysUser.getCardId());
//        判断身份证号格式
        if(!valid)return Result.build(null,402,"身份证格式错误");
//        将信息存入数据库
        if(this.update(Wrappers.<SysUser>lambdaUpdate().eq(SysUser::getUid,id).set(SysUser::getCardId,sysUser.getCardId()).set(SysUser::getCardName,sysUser.getCardName()).set(SysUser::getSex,sysUser.getSex()).set(SysUser::getStatus,1))) {
            return Result.build(null, 200, "实名认证成功");
        }else {
            return Result.build(null, 500, "实名认证失败");
        }
        }

//        获取数据库用户信息
    @Override
    public SysUser getUserInfo(Integer uid) {
        return this.getById(uid);
    }

    @Override
    public Result isDeposit(SysUser sysUser) {
//        判断押金状态 是否为空
//        if(sysUser.getDeposit()==null || sysUser.getDeposit()<=0){
//            return "缴纳押金";
//        }else {
//            return "退还押金";
//        }
//        引入登录token获取用户信息
        //        引入登录token
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String header = request.getHeader("Authorization");
        String data = stringRedisTemplate.opsForValue().get("login:data:" + header);
        if (StringUtils.isEmpty(data)){
            return Result.build(null,ResultCodeEnum.LOGIN_ERROR);
        }
        Map<String, Object> map = JwtService.getClaimsMap(data);
        Integer  id = Integer.valueOf(map.get("userId").toString());
//        根据用户id判断押金是否为空
        if(this.getById(id).getDeposit()==null || this.getById(id).getDeposit()<=0){
            return Result.build(null,402,"未缴纳");
        }else {
            return Result.build(null,200,"已缴纳");
        }
    }
//押金添加
    @Override
    public Result addDeposit(SysUser sysUser) {
//        引入登录token
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String header = request.getHeader("Authorization");
        String data = stringRedisTemplate.opsForValue().get("login:data:" + header);
        if (StringUtils.isEmpty(data)){
            return Result.build(null,ResultCodeEnum.LOGIN_ERROR);
        }
        Map<String, Object> map = JwtService.getClaimsMap(data);
        Integer  id = Integer.valueOf(map.get("userId").toString());
        if(this.update(Wrappers.<SysUser>lambdaUpdate().eq(SysUser::getUid,id).set(SysUser::getDeposit,sysUser.getDeposit()))) {
            return Result.build(null, 200, "押金添加成功");
        }else {
            return Result.build(null, 500, "押金添加失败");
        }
    }

    @Override
    public Result logout() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String uuid = request.getHeader("authorization");
        String s = stringRedisTemplate.opsForValue().get("login:data:" + uuid);
        stringRedisTemplate.delete("login:data:"+uuid);
        stringRedisTemplate.opsForHash().delete("login:data","login:user:"+uuid);
        return Result.build(null,200,"退出成功");
    }
}




